import { Material, Mesh, Object3D, Texture } from 'three';

export class AssetManager {
  private resources: Set<Object3D | Material | Texture>;

  constructor() {
    this.resources = new Set<Object3D | Material | Texture>();
  }

  track(resource: unknown): void {
    if (!resource) {
      return;
    }

    if (Array.isArray(resource)) {
      resource.forEach((item) => this.track(item));
      return;
    }

    if (resource instanceof Object3D || (resource as any).dispose instanceof Function) {
      this.resources.add(resource as Object3D | Material | Texture);
    }

    if (resource instanceof Object3D) {
      this.track(resource.children);
    } else if (resource instanceof Mesh) {
      this.track(resource.geometry);
      this.track(resource.material);
    } else if (resource instanceof Material) {
      if ('map' in resource && resource.map instanceof Texture) {
        this.track(resource.map);
      }

      // Other material properties tracking...
    }

    // Other resource types tracking...
  }

  untrack(resource: unknown): void {
    this.resources.delete(resource as Object3D | Material | Texture);
  }

  dispose(): void {
    this.resources.forEach((resource) => {
      if (resource instanceof Object3D) {
        resource.parent?.remove(resource);
      }

      if ((resource as any).dispose instanceof Function) {
        (resource as any).dispose();
      }
    });

    this.resources.clear();
  }
}
